﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace Notoric.Gui.Controls
{
    /// <summary>
    /// Interaction logic for RtfTextSectionInterior.xaml
    /// </summary>
    public partial class RtfTextSectionInterior : UserControl
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="RtfTextSectionInterior"/> class.
        /// </summary>
        public RtfTextSectionInterior()
        {
            InitializeComponent();
        }

        #endregion

        #region Dependency Properties Identifiers

        /// <summary>
        /// Identifies the <see cref="Document"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty DocumentProperty = DependencyProperty.Register(
            "Document", typeof(FlowDocument), typeof(RtfTextSectionInterior), new PropertyMetadata(DocumentProperty_ValueChanged)
            );

        #endregion

        #region Event Handlers
        
        /// <summary>
        /// Occurs when the value of the <see cref="Document"/> dependency property has changed.
        /// </summary>
        /// <param name="d">The dependency object that has sent the event</param>
        /// <param name="e">Event data.</param>
        private static void DocumentProperty_ValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control = (RtfTextSectionInterior)d;
            control.PART_TextBox.Document = (FlowDocument)e.NewValue;
        }

        /// <summary>
        /// Occurs when the rich text box got focus.
        /// </summary>
        /// <param name="sender">Object where the event handler is attached</param>
        /// <param name="e">Event data</param>
        private void PART_TextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            interior.Selection = PART_TextBox.Selection;
        }

        /// <summary>
        /// Occurs when the rich text box has lost the focus.
        /// </summary>
        /// <param name="sender">Object where the event handler is attached</param>
        /// <param name="e">Event data</param>
        private void PART_TextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            interior.Selection = null;
            var cmd = interior.CreateSetContentCommand(PART_TextBox.Document);

            cmd.Execute(null);
        }

        /// <summary>
        /// Occurs when the data context (visualized section interior) of this control has changed.
        /// </summary>
        /// <param name="sender">Object that has sent the event</param>
        /// <param name="e">Event data</param>
        private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (interior != null)
                interior.NeedsToClearSelection -= interior_NeedsToClearSelection;

            interior = (ViewModel.Elements.RtfTextSectionInterior)DataContext;

            if (interior != null)
                interior.NeedsToClearSelection += new EventHandler(interior_NeedsToClearSelection);
        }

        /// <summary>
        /// Occurs when the <see cref="ViewModel.Elements.RtfTextSectionInterior.NeedsToClearSelection"/> event is raised on the visualized section interior.
        /// </summary>
        /// <param name="sender">Object that has sent the event</param>
        /// <param name="e">Event data</param>
        private void interior_NeedsToClearSelection(object sender, EventArgs e)
        {
            PART_TextBox.Selection.Select(PART_TextBox.Document.ContentStart, PART_TextBox.Document.ContentStart);
        }

        /// <summary>
        /// Occurs when the text selection has changed.
        /// </summary>
        /// <param name="sender">Object where the event handler is attached</param>
        /// <param name="e">Event data</param>
        private void PART_TextBox_SelectionChanged(object sender, RoutedEventArgs e)
        {
            interior.Selection = PART_TextBox.Selection;
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets or sets the presented document.
        /// </summary>
        /// <value>
        /// <para>
        /// Type: <see cref="FlowDocument"/>
        /// </para>
        /// <para>
        /// The presented document.
        /// </para>
        /// </value>
        public FlowDocument Document
        {
            get { return (FlowDocument)GetValue(DocumentProperty); }
            set { SetValue(DocumentProperty, value); }
        }

        #endregion

        #region Private Fields

        /// <summary>
        /// Holds the visualized section interior.
        /// </summary>
        private ViewModel.Elements.RtfTextSectionInterior interior;

        #endregion
    }
}
